/*
 *    Copyright (c) 2018-2025, nart All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: nart
 */
package com.nai365.nart.member.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nai365.nart.common.core.util.R;
import com.nai365.nart.common.core.vo.WalletChangeVo;
import com.nai365.nart.common.security.util.SecurityUtils;
import com.nai365.nart.member.entity.Member;
import com.nai365.nart.member.entity.Wallet;
import com.nai365.nart.member.entity.WalletChange;
import com.nai365.nart.member.mapper.WalletMapper;
import com.nai365.nart.member.service.MemberService;
import com.nai365.nart.member.service.WalletChangeService;
import com.nai365.nart.member.service.WalletService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 钱包表
 *
 * @author baogs
 * @date 2022-07-07 09:46:29
 */
@Service
@AllArgsConstructor
public class WalletServiceImpl extends ServiceImpl<WalletMapper, Wallet> implements WalletService {


	private final WalletChangeService walletChangeService;

	private final MemberService memberService;

	/*
	 *
	 * 修改钱包信息
	 * */
	@Override
	public boolean updateMoney(Wallet wallet) {
		String reason = wallet.getReason();
		Long id = SecurityUtils.getUser().getId();
		WalletChange walletChange = new WalletChange();
		walletChange.setRmbValue(wallet.getRmbValue());
		walletChange.setNartValue(wallet.getNartValue());
		walletChange.setOperateBy(id);
		walletChange.setUserId(id);
		walletChange.setSkuName(reason);
		walletChangeService.save(walletChange);

		if (StrUtil.isNotBlank(reason) && "签到".equals(reason)){
			wallet.setReason(null);
		}
		wallet.setRmbBalance(wallet.getRmbBalance().add(wallet.getRmbValue()));
		wallet.setNartBalance(wallet.getNartBalance().add(wallet.getNartValue()));
		this.updateById(wallet);

		return true;
	}

	/*
	 * 得到wallet数据，如果没有就创建后再得到
	 * */
	@Override
	public Wallet getWalletById(Long id) {
		long id1 = SecurityUtils.getUser().getId();
		Wallet byId = this.getById(id1);
		if(byId == null){
			Wallet wallet = new Wallet();
			wallet.setId(id1);
			wallet.setUserId(id1);
			wallet.setPhone(SecurityUtils.getUser().getPhone());
			this.save(wallet);
			return wallet;
		}
		return this.getById(id);
	}


	/**
	 * yuran
	 * 更新所有手机号
	 * 根据wallet表中的userId从member表获取手机号，更新全表
	 */
	@Override
	public void updateAllPhone(){
		List<Wallet> list = this.list();
		/*List<Long> userIdList = list.stream().map(item -> {
			return item.getUserId();
		}).collect(Collectors.toList());*/
		for(Wallet wallet:list){
			Member member = memberService.getById(wallet.getUserId());
			if (member != null){
				wallet.setPhone(member.getMobile());
				this.updateById(wallet);
			}
		}

	}

	@Override
	public R<Wallet> getWalletInner(Long userId) {
		Wallet byId = getBaseMapper().selectOne(Wrappers.<Wallet>lambdaQuery().eq(Wallet::getUserId , userId));
		if(byId == null){
			Wallet wallet = new Wallet();
			wallet.setId(userId);
			wallet.setUserId(userId);
			Member byId1 = memberService.getById(userId);
			wallet.setPhone(byId1.getMobile());
			save(wallet);
			return R.ok(wallet);
		} else {
			BigDecimal freezeNart = byId.getFreezeNart();
			BigDecimal yhdBalance = byId.getNartBalance();
			byId.setNartBalance(yhdBalance.subtract(freezeNart));
			return R.ok(byId);
		}
	}

	@Override
	public R changeWallet(WalletChangeVo changeVo) {
		Wallet wallet1 = this.getBaseMapper().selectOne(Wrappers.<Wallet>lambdaQuery().eq(Wallet::getUserId, changeVo.getToUserId()));

		WalletChange walletChange = new WalletChange();
		BeanUtil.copyProperties(changeVo , walletChange);
		walletChange.setOperateBy(changeVo.getFromUserId());
		walletChange.setUserId(changeVo.getFromUserId());
		walletChange.setCurrentBalance(wallet1.getRmbBalance().add(changeVo.getRmbValue()));
		walletChangeService.save(walletChange);


		Wallet wallet = getWallet(changeVo.getToUserId());
		System.out.println("wallet.getRmbBalance()-------------------"+wallet.getRmbBalance());
		System.out.println("changeVo.getRmbValue()-------------"+changeVo.getRmbValue());
		System.out.println("wallet.getRmbBalance().add(changeVo.getRmbValue())-------"+wallet.getRmbBalance().add(changeVo.getRmbValue()));
		wallet.setRmbBalance(wallet.getRmbBalance().add(changeVo.getRmbValue()));
		wallet.setNartBalance(wallet.getNartBalance().add(changeVo.getNartValue()));
		wallet.setUpdateTime(null);
		return R.ok(this.updateById(wallet));
	}

	@Override
	public R changeWallet(List<WalletChangeVo> changeVos) {
		List<WalletChange> walletChanges = new ArrayList<>();
		List<Wallet> wallets = new ArrayList<>();

		changeVos = changeVos.parallelStream().collect(Collectors.toMap(WalletChangeVo::getToUserId, item -> item, (item1, item2) -> {
			item1.setRmbValue(item1.getRmbValue().add(item2.getRmbValue()));
			item1.setNartValue(item1.getNartValue().add(item2.getNartValue()));
			return item1;
		})).values().parallelStream().collect(Collectors.toList());

		changeVos.parallelStream().forEach(changeVo ->{
			WalletChange walletChange = new WalletChange();
			BeanUtil.copyProperties(changeVo , walletChange);
			walletChange.setOperateBy(changeVo.getFromUserId());
			walletChange.setUserId(changeVo.getFromUserId());
			//		walletChangeService.save(walletChange);
			walletChanges.add(walletChange);

			//		Wallet wallet = this.getBaseMapper().selectOne(Wrappers.<Wallet>lambdaQuery().eq(Wallet::getUserId, changeVo.getToUserId()));

			Wallet wallet = getWallet(changeVo.getToUserId());
			wallet.setRmbBalance(wallet.getRmbBalance().add(changeVo.getRmbValue()));
			wallet.setNartBalance(wallet.getNartBalance().add(changeVo.getNartValue()));
			wallet.setUpdateTime(null);
			wallets.add(wallet);
		});
		walletChangeService.saveBatch(walletChanges);
//		updateBatchById(wallets);
		return R.ok(updateBatchById(wallets));
	}

	@Override
	public Wallet getWallet(Long id) {
		Long id1 = id;
		Wallet byId = this.getById(id1);
		if (id == null){
			id1 = Long.valueOf(SecurityUtils.getUser().getId());
		}
		if(byId == null){
			Member byId1 = memberService.getById(id1);
			Wallet wallet = new Wallet();
			wallet.setId(id1);
			wallet.setUserId(id1);
			wallet.setRmbBalance(BigDecimal.ZERO);
			wallet.setNartBalance(BigDecimal.ZERO);
			wallet.setNewRmbBalance(BigDecimal.ZERO);
			wallet.setNewNartBalance(BigDecimal.ZERO);
			if (byId1 !=null) {
				wallet.setPhone(byId1.getMobile());
			}
			this.save(wallet);
			return wallet;
		} else {
			return byId;
		}
	}

	@Override
	public Wallet findWalletByUserId(Long userId) {
		LambdaQueryWrapper<Wallet> walletLambdaQueryWrapper = new LambdaQueryWrapper<>();
		walletLambdaQueryWrapper.eq(Wallet::getUserId,userId);
		return this.getOne(walletLambdaQueryWrapper);
	}
}
